
import 'dart:io';

import 'package:baselib/utils/file_util.dart';
import 'package:baselib/utils/image_util.dart';
import 'package:baselib/utils/keyboard_util.dart';
import 'package:baselib/utils/load_util.dart';
import 'package:baselib/utils/log_util.dart';
import 'package:baselib/utils/md5_util.dart';
import 'package:baselib/utils/navigator_util.dart';
import 'package:baselib/utils/permissions_helper.dart';
import 'package:baselib/utils/toast_util.dart';
import 'package:baselib/widgets/dialog_util.dart';
import 'package:baselib/widgets/refresh_util.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:framelib/base/base_view_model.dart';
import 'package:framelib/config/api_config.dart';
import 'package:framelib/config/route_config.dart';
import 'package:framelib/net/baseentity.dart';
import 'package:framelib/utils/color_util.dart';
import 'package:framelib/utils/string_util.dart';
import 'package:framelib/widgets/chat_room_oper_widget.dart';
import 'package:framelib/widgets/page_widget.dart';
import 'package:get/state_manager.dart';
import 'package:get/get.dart';
import 'package:module_business/module_chat/model/gift_entity.dart';
import 'package:module_business/module_chat/service/module_chat_service.dart';
import 'package:module_business/module_chat/view/gifts_bottom_sheet_widget.dart';
import 'package:module_business/module_comm/model/user_entity.dart';
import 'package:module_business/module_comm/model/user_params_model.dart';
import 'package:module_business/module_comm/service/module_comm_service.dart';
import 'package:module_business/module_index/model/voice_person_entity.dart';
import 'package:module_business/module_index/service/module_index_service.dart';
import 'package:module_business/module_my/service/module_my_service.dart';
import 'package:nim_core/nim_core.dart';
import 'package:get/get.dart';
import 'package:pull_to_refresh_flutter3/pull_to_refresh_flutter3.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:image_picker/image_picker.dart';
import 'package:video_player/video_player.dart';


class ChatViewModel extends BaseViewModel<ModuleChatService>{

  ModuleChatService moduleChatService;
  ModuleMyService   moduleMyService;
  RefreshController refreshController = RefreshController(initialRefresh: true);
  RefreshState loadStatus=RefreshState.OK;
  int page = 1;
  bool isCanMoreData = false;
  String voicePersonYxAccid;
  String voicePersonUserId;
  String voicePersonNickName;
  String voicePersonIcon;
  final ImagePicker _picker = ImagePicker();
  Rx<List<NIMMessage>> msgDatas = Rx<List<NIMMessage>>([]);
  // String comments = '';

  TextEditingController commentController = TextEditingController();
  ScrollController commentScrollController = ScrollController();

  RxBool recording = false.obs;

  RxBool emojiSelected = false.obs;
  RxBool voiceSelected = false.obs;
  RxBool pictureSelected = false.obs;
  RxBool videoSelected = false.obs;

  //礼物列表
  List<GiftEntity> giftsDatas = [];

  @override
  ModuleChatService createService(){
    moduleMyService = ModuleMyService();
    return moduleChatService = ModuleChatService();
  }

  @override
  void onInit() {
    super.onInit();
    Map<String,dynamic> arguments = Get.arguments??{};
    voicePersonYxAccid =  arguments['voicePersonYxAccid'];
    voicePersonUserId =  arguments['voicePersonUserId'];
    voicePersonNickName =  arguments['voicePersonNickName'];
    voicePersonIcon =  arguments['voicePersonIcon'];
    //设置监听
    setLinsener();
    //查询最近的消息
    queryHostoryMsgs();
    //获取黑名单
    getMyBlacks();
    //获取礼物列表
    getGiftsList();
  }
  @override
  void onClose() {
    if(commentController!=null)commentController.dispose();
    if(commentScrollController!=null)commentScrollController.dispose();
    super.onClose();
  }
  onRefresh({int pageCur,}) async{
    if(pageCur!=null)page=pageCur;
    NIMResult<List<NIMMessage>> result = await NimCore.instance.messageService.queryMessageList(
        voicePersonYxAccid,
        NIMSessionType.p2p,
        100);
    if(refreshController!=null)refreshController.refreshCompleted();
    if(refreshController!=null)refreshController.loadComplete();
    if(result?.isSuccess??false){

      msgDatas.value = result?.data??[];
      LogUtil.d('ChatViewModel--->dataLists=${msgDatas.value.map((e) => e?.toMap())?.toList()}');
      if(msgDatas.value.isNotEmpty){
        NimCore.instance.messageService.sendMessageReceipt(sessionId: msgDatas.value[msgDatas.value.length-1]?.fromAccount, message: msgDatas.value[msgDatas.value.length-1]);
      }
      // for (NIMMessage m in msgDatas.value) {
      //   if (m.sessionType == NIMSessionType.p2p) {
      //     NimCore.instance.messageService.sendMessageReceipt(sessionId: m?.sessionId, message: m);
      //   } else if (m.sessionType == NIMSessionType.team) {
      //     NimCore.instance.messageService.sendTeamMessageReceipt(m);
      //   }
      // }
      msgDatas.refresh();
    }
  }
  void queryHostoryMsgs() async{

  }

  void setLinsener() {
    NimCore.instance.messageService.onMessageStatus.listen((NIMMessage message) {
      LogUtil.d('ChatViewModel,onMessageStatus--->message=${message?.toMap()}');
      // 1、根据sessionId判断是否是自己的消息
      // 2、更改内存中消息的状态
      // 3、刷新界面
      //otherAccId--->d57c138c56fa4c42aac34e6d606edfb8
      //selfAccId--->87118bd5619640f6a8c408533479d9a4
      if((message?.sessionId == UserParamsModel.instance.yxAccid)&&(message?.messageDirection==NIMMessageDirection.received)){
        msgDatas.value.add(message);
        msgDatas.refresh();
      }
    });
    NimCore.instance.messageService.onMessage.listen((List<NIMMessage> messages) {
      LogUtil.d('ChatViewModel,onMessage--->message=${messages?.map((e) => e?.toMap())?.toList()}');
      // 处理新收到的消息，为了上传处理方便，SDK 保证参数 messages 全部来自同一个聊天对象。
      for (NIMMessage m in messages) {
        if (m.sessionType == NIMSessionType.p2p) {
          NimCore.instance.messageService.sendMessageReceipt(sessionId: m?.sessionId, message: m);
          msgDatas.value.add(m);
        } else if (m.sessionType == NIMSessionType.team) {
          NimCore.instance.messageService.sendTeamMessageReceipt(m);
        }
      }
      msgDatas.refresh();
    });

    NimCore.instance.messageService.onMessageReceipt.listen((event) {
      LogUtil.d('ChatViewModel,onMessageReceipt--->event=${event?.toString()}');
      print('Test_Observer onMessageReceipt ${event.toString()}');
    });
  }
  //查询我的拉黑用户列表
  void getMyBlacks() async{
    Map<String,dynamic> upData={
      "currentPage":1,
      "pageSize":100000,
    };
    UserParamsModel.instance.setMyBlackIds([]);
    BaseEntity baseEntity = await moduleMyService.api_user_blackList(parmsMap: upData);
    if(baseEntity?.code == ApiConfig.SUCCESS_CODE){
      List<UserEntity> myBlackTemps = baseEntity?.result??[];
      if(myBlackTemps.isNotEmpty){
        var myBlackIds = myBlackTemps.map((e) => '${e?.userId}').toList();
        LogUtil.d('getMyBlacks--->myBlackIds=$myBlackIds');
        UserParamsModel.instance.setMyBlackIds(myBlackIds);
      }
    }
    update();
  }
  //拉黑
  void startBlack() async{
    LoadUtil.showLoad(loadingText: '${StringUtil.instance.submiting}...');
    Map<String,dynamic> upData={
      "type": 1,
      "userId": voicePersonUserId,
      "yxAccid": voicePersonYxAccid
    };
    BaseEntity baseEntity = await moduleMyService.api_user_BlackOrRemove(parmsMap: upData,
        isBlack: !isInBlackList());
    LoadUtil.hideLoad();
    if(baseEntity?.code == ApiConfig.SUCCESS_CODE){
      //查询我的拉黑用户列表
      getMyBlacks();
    }else{
      ToastUtil.toast(baseEntity?.message);
    }
  }
  // onCommentChanged(String value) {
  //   comments = value;
  // }
  sendMsg() async{
    dynamic comments = commentController.text;
    if((comments??'').isEmpty)return;
    // LoadUtil.showLoad(loadingText: StringUtil.instance.Sending);
    // 帐号
    String account = voicePersonYxAccid;
    // 以单聊类型为例
    NIMSessionType sessionType = NIMSessionType.p2p;
    String text = comments;
    // 创建并且发送一个文本消息
    NIMResult<NIMMessage> createResult = await MessageBuilder.createTextMessage(
        sessionId: account, sessionType: sessionType, text: text);
    if(createResult?.isSuccess??false){
      NIMResult<NIMMessage> sendMessageResult = await NimCore.instance.messageService.sendMessage(message: createResult.data, resend: false);
      // LoadUtil.hideLoad();
      if(sendMessageResult?.isSuccess??false){
        commentController.clear();
        msgDatas.value.add(sendMessageResult.data);
        msgDatas.refresh();
      }else{
        ToastUtil.toast(sendMessageResult?.errorDetails);
      }
    }else{
      // LoadUtil.hideLoad();
      ToastUtil.toast(createResult?.errorDetails);
    }

  }

  sendAudioMessage(String filePath, int fileSize, int duration) async{
    LogUtil.d('audioMessageCallBack--->filePath=$filePath,fileSize=$fileSize,duration=$duration,');
    if(duration<200){
      ToastUtil.toast(StringUtil.instance.Please_press_to_speak);
      return;
    }
    // 该帐号为示例
    String account = voicePersonYxAccid;
// 以单聊类型为例
    NIMSessionType sessionType = NIMSessionType.p2p;
// 示例音频，需要开发者在相应目录下有文件
    File file = new File(filePath);
    // 显示名称
    String displayName = FileUtil.getFileName(filePath: filePath);
    // web 端需要base64,其他端可忽略
    String base64 = 'this is base64';
// 发送语音消息
    NIMResult<NIMMessage> createResult =
    await MessageBuilder.createAudioMessage(
        sessionId: account,
        sessionType: sessionType,
        filePath: file.path,
        fileSize: file.lengthSync(),
        duration: duration,
        displayName: displayName,
    );
    if(createResult?.isSuccess??false){
      NIMResult<NIMMessage> sendMessageResult = await NimCore.instance.messageService.sendMessage(message: createResult.data, resend: false);
      if(sendMessageResult?.isSuccess??false){
        commentController.clear();
        msgDatas.value.add(sendMessageResult.data);
        msgDatas.refresh();
      }else{
        ToastUtil.toast(sendMessageResult?.errorDetails);
      }
    }else{
      ToastUtil.toast(createResult?.errorDetails);
    }
  }

  bool isOpenButtonUi() {
    return emojiSelected.value||voiceSelected.value||pictureSelected.value||videoSelected.value;
  }

  emojiSelect() {
    emojiSelected.value=!(emojiSelected.value??false);
    voiceSelected.value= false;
    pictureSelected.value = false;
    videoSelected.value = false;
  }
  voiceSelect() {
    voiceSelected.value=!(voiceSelected.value??false);
    pictureSelected.value = false;
    videoSelected.value = false;
    emojiSelected.value = false;
  }

  pictureSelect() async{
    // pictureSelected.value=!(pictureSelected.value??false);
    pictureSelected.value= false;
    voiceSelected.value = false;
    videoSelected.value = false;
    emojiSelected.value = false;
    //弹出选择图片
    if (await PermissionsHelper.requestPermission(Platform.isIOS ? [Permission.photos] : [Permission.storage])) {
      _pickImage();
    }
  }
  _pickImage() async {
    final List<XFile> pickedFileList = await _picker.pickMultiImage();
    if (pickedFileList != null) {
      for (XFile image in pickedFileList) {
        int len = await image.length();
        sendImageMessage(image.path, len);
      }
    }
  }
  void sendImageMessage(String filePath, int fileSize, {NIMMessage replyMsg}) async{
    NIMResult<NIMMessage> createResult =
    await MessageBuilder.createImageMessage(
        sessionId: voicePersonYxAccid,
        sessionType: NIMSessionType.p2p,
        filePath: filePath,
        fileSize: fileSize);
    if(createResult?.isSuccess??false){
      NIMResult<NIMMessage> sendMessageResult = await NimCore.instance.messageService
          .sendMessage(message: createResult.data, resend: false);
      if(sendMessageResult?.isSuccess??false){
        msgDatas.value.add(sendMessageResult.data);
        msgDatas.refresh();
      }else{
        ToastUtil.toast(sendMessageResult?.errorDetails);
      }
    }else{
      ToastUtil.toast(createResult?.errorDetails);
    }
  }
  videoSelect() {
    // videoSelected.value=!(videoSelected.value??false);
    videoSelected.value= false;
    voiceSelected.value = false;
    pictureSelected.value = false;
    emojiSelected.value = false;
    _pickVideo();
  }
  _pickVideo() async {
    final XFile video = await _picker.pickVideo(source: ImageSource.gallery);
    if (video != null) {
      LoadUtil.showLoad(loadingText: '${StringUtil.instance.submiting}...');
      VideoPlayerController controller = VideoPlayerController.file(File(video.path));
      await controller.initialize();
      sendVideoMessage(
          video.path,
          controller.value.duration.inMilliseconds,
          controller.value.size.width.toInt(),
          controller.value.size.height.toInt(),
          video.name);
    }
  }
  void sendVideoMessage(
      String filePath, int duration, int width, int height, String displayName,
      {NIMMessage replyMsg}) async{
    NIMResult<NIMMessage> createResult =
    await MessageBuilder.createVideoMessage(
        sessionId: voicePersonYxAccid,
        sessionType: NIMSessionType.p2p,
        filePath: filePath,
        duration: duration,
        width: width,
        height: height,
        displayName: displayName);
    if(createResult?.isSuccess??false){
      NIMResult<NIMMessage> sendMessageResult = await NimCore.instance.messageService
          .sendMessage(message: createResult.data, resend: false);
      LoadUtil.hideLoad();
      if(sendMessageResult?.isSuccess??false){
        msgDatas.value.add(sendMessageResult.data);
        msgDatas.refresh();
      }else{
        ToastUtil.toast(sendMessageResult?.errorDetails);
      }
    }else{
      LoadUtil.hideLoad();
      ToastUtil.toast(createResult?.errorDetails);
    }
  }
  bool isInBlackList() {
    return UserParamsModel.instance.myBlackIds.contains('${voicePersonUserId??('-1000')}');
  }
  showChatOper() {
    showModalBottomSheet(
        context: Get.context,
        isScrollControlled: true,
        backgroundColor: ColorUtil.instance.color_transparent,
        builder: (BuildContext context){
          return ChatRoomOperWidget(
            isInBlackList: isInBlackList(),
            reportSelectedFunc: (){
              startReport();
            },
            blackSelectedFunc: (){
              startBlack();
            },
          );
        }
    );
  }
  void startReport() {
    // LoadUtil.showLoad(loadingText: '${StringUtil.instance.submiting}...');
    // Future.delayed(Duration(milliseconds: 500), ()=>LoadUtil.hideLoad());
    // ToastUtil.toast(StringUtil.instance.Report_Success);
    NavigatorUtil.pushByName(RouteConfig.reportPage,arguments: {
      'beBlockUid': '${voicePersonUserId}'
    });
  }

  openGiftsUi() {
    DialogUtil.instance.showCommBottomSheet(
        isScrollControlled: true,
        child: GiftsBottomSheetWidget(
            onSend: (GiftEntity giftEntity,int giftNum){
              NavigatorUtil.goBack();
              LogUtil.d('openGiftsUi-->giftNum=$giftNum,giftEntity=${giftEntity?.toJson()}');
              //发起送礼
              sendGifts(giftEntity,giftNum);
            },
        )
    );
  }

  toPersonHome() {
    NavigatorUtil.pushByName(RouteConfig.otherPersonHomePage,arguments: {
      'userId': '$voicePersonUserId'
    });
  }

  void getGiftsList() async{
    Map<String,dynamic> upData={};
    BaseEntity baseEntity = await moduleMyService.api_voicechat_gift_list(parmsMap: upData);
    if(baseEntity?.code == ApiConfig.SUCCESS_CODE){
      giftsDatas = baseEntity?.result??[];
    }
    update();
  }

  void sendGifts(GiftEntity giftEntity, int giftNum) async{
    LoadUtil.showLoad(loadingText: StringUtil.instance.Sending);
    Map<String,dynamic> parmsMap= {
      "giftId": giftEntity?.id,
      "giftNum": giftNum,
      "payType": 1,
      // "roomId": 0,
      "userId": voicePersonUserId
    };
    LogUtil.d('sendGifts--->parmsMap=$parmsMap');
    LogUtil.d('sendGifts--->myuserId=${UserParamsModel.instance.userId}');
    BaseEntity baseEntity = await moduleMyService.api_voicechat_gift_sendGift(parmsMap: parmsMap);
    LoadUtil.hideLoad();
    if(baseEntity?.code == ApiConfig.SUCCESS_CODE){
      ToastUtil.toast(StringUtil.instance.Send_success);
    }else{
      ToastUtil.toast(baseEntity?.message);
    }
  }
}
